package com.shanzmoo.admin.manager.store;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shanzmoo.admin.domain.dto.StoreReceiveBillDetailSaveDTO;
import com.shanzmoo.admin.domain.dto.StoreReceiveBillSaveDTO;
import com.shanzmoo.admin.domain.dto.StoreReceiveBillUpdateDTO;
import com.shanzmoo.admin.domain.dto.StoreStockAllotBillDetailSaveDTO;
import com.shanzmoo.admin.manager.store.StorePurchaseBillManager;
import com.shanzmoo.base.bean.SHttpResponse;
import com.shanzmoo.base.bean.SResponse;
import com.shanzmoo.base.constant.e.SysBillTypeEnum;
import com.shanzmoo.base.exception.StoreException;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.core.manager.CodeManager;
import com.shanzmoo.db.store.entity.*;
import com.shanzmoo.db.store.entity.bo.StoreReceiveSkuSelectBO;
import com.shanzmoo.db.store.entity.query.StoreReceiveBillQuery;
import com.shanzmoo.db.store.entity.vo.StoreReceiveBillDetailVO;
import com.shanzmoo.db.store.entity.vo.StoreReceiveBillVO;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.db.store.service.IStorePurchaseBillService;
import com.shanzmoo.db.store.service.IStoreReceiveBillDetailService;
import com.shanzmoo.db.store.service.IStoreReceiveBillService;
import com.shanzmoo.db.store.service.IStoreReceivePutawayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 仓库收货单 管理器
 *
 * @author Gzhao 2021-03-11
 */
@Slf4j
@Component
public class StoreReceiveBillManager {

    @Autowired
    private CodeManager codeManager;
    @Autowired
    private IStoreReceiveBillService storeReceiveBillService;
    @Autowired
    private IStoreReceiveBillDetailService storeReceiveBillDetailService;
    @Autowired
    private StorePurchaseBillManager storePurchaseBillManager;
    @Autowired
    private IStoreReceivePutawayService storeReceivePutawayService;

    /**
     * 分页查询
     */
    public PageRespBase<StoreReceiveBillVO> queryPage(StoreReceiveBillQuery query) {
        Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<StoreReceiveBillVO> reList = storeReceiveBillService.queryPageList(query);

        if (CollUtil.isNotEmpty(reList)) {
            List<Integer> billIds = reList.stream().map(StoreReceiveBillVO::getId)
                    .collect(Collectors.toList());

            List<StoreReceiveBillDetailVO> detailAllList = storeReceiveBillDetailService.queryListByIds(billIds);
            for (StoreReceiveBillVO billVO : reList) {
                List<StoreReceiveBillDetailVO> detailList = detailAllList.stream()
                        .filter(e -> e.getBillId().equals(billVO.getId()))
                        .collect(Collectors.toList());
                billVO.setDetailList(detailList);
            }
        }

        PageRespBase<StoreReceiveBillVO> result = PageRespBase.create(page, reList);
        PageHelper.clearPage();
        return result;
    }

    /**
     * 取消收货单
     *
     * @author Gzhao 2021/3/11
     * @param id 收货单id
     * @return
     */
    public SResponse<Boolean> cancel(Integer id) {
        /**
         * 1. 校验收货单状态
         * 2. 更改收货单状态
         */
        beforeOperation(id);
        StoreReceiveBillEntity billEntity = new StoreReceiveBillEntity();
        billEntity.setId(id);
        billEntity.setStatus(9);
        storeReceiveBillService.updateById(billEntity);
        return SResponse.ok(Boolean.TRUE);
    }

//    /**
//     * 更新收货单
//     *
//     * @author Gzhao 2021/3/11
//     * @param updateDto 收货单更新信息
//     * @return
//     */
//    @Transactional(rollbackFor = Exception.class)
//    public SResponse<Boolean> update(StoreReceiveBillUpdateDTO updateDto) {
//        // todo
//
//        return SResponse.ok(Boolean.TRUE);
//    }

    /**
     *
     *
     * @author Gzhao 2021/3/11
     * @param id  收货单id
     * @return
     */
    public SResponse<StoreReceiveBillVO> getInfo(Integer id) {
        StoreReceiveBillVO billVO = storeReceiveBillService.getInfoById(id);
        List<StoreReceiveBillDetailVO> detailList = storeReceiveBillDetailService.getListInfoByBillId(id);
        billVO.setDetailList(detailList);
        return SResponse.ok(billVO);
    }

    /**
     * 审核收货单入库
     *
     * @author Gzhao 2021/3/11
     * @param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public SResponse<Boolean> examine(Integer id) {
        //1. 校验收货单状态
        beforeOperation(id);

        //2. 更改收货单状态
        StoreReceiveBillEntity billEntity = new StoreReceiveBillEntity();
        billEntity.setId(id);
        billEntity.setStatus(1);
        billEntity.setExamineUser(CurrentUserCache.getUserId());
        billEntity.setExamineTime(LocalDateTime.now());
        storeReceiveBillService.updateById(billEntity);

        //3. 更新上架数
        List<StoreReceiveBillDetailEntity> billDetailList = storeReceiveBillDetailService.lambdaQuery()
                .eq(StoreReceiveBillDetailEntity::getDeleted, false)
                .eq(StoreReceiveBillDetailEntity::getBillId, billEntity.getId())
                .list();

        List<StoreReceivePutawayEntity> putawayList = new ArrayList<>();
        for (StoreReceiveBillDetailEntity billDetail : billDetailList) {
            StoreReceivePutawayEntity putawayEntity = new StoreReceivePutawayEntity();
            putawayEntity.setStatus(0);
            putawayEntity.setSku(billDetail.getSku());
            putawayEntity.setSkuNum(billDetail.getSkuNum());
            putawayEntity.setReceiveBillId(billDetail.getBillId());
            putawayList.add(putawayEntity);
        }
        storeReceivePutawayService.saveBatch(putawayList);

        return SResponse.ok();
    }

    /**
     * 保存收货单
     * @param saveDto
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveReceiveBill(StoreReceiveBillSaveDTO saveDto) {
        StoreReceiveBillEntity billEntity = saveDto.convertEntity();
        if(billEntity.getId() == null){
            billEntity.setBillNo(codeManager.generateBillNo(SysBillTypeEnum.RECEIVE_BILL));
            billEntity.setCreateUser(CurrentUserCache.getUserId());
        }else{
            //修改判断状态
            beforeOperation(billEntity.getId());
        }
        storeReceiveBillService.saveOrUpdate(billEntity);
        //如编辑,先删除原有
//        List<StoreReceiveBillDetailEntity> oldDetails = storeReceiveBillDetailService.list(Wrappers.<StoreStockAllotBillDetailEntity>lambdaQuery()
//                .eq(StoreReceiveBillDetailEntity::getBillId,billEntity.getId()));
        List<StoreReceiveBillDetailEntity> oldDetails = storeReceiveBillDetailService.list(new QueryWrapper<StoreReceiveBillDetailEntity>()
                .eq("bill_id", billEntity.getId()).eq("deleted",Boolean.FALSE));
        if(CollUtil.isNotEmpty(oldDetails)){
            oldDetails.stream().forEach(r -> {
                r.setDeleted(true);
            });
            storeReceiveBillDetailService.updateBatchById(oldDetails);
        }
        //插入
        List<StoreReceiveBillDetailSaveDTO> detailList = saveDto.getDetailList();
        List<StoreReceiveBillDetailEntity> rsList = detailList.stream()
                .map(StoreReceiveBillDetailSaveDTO::convertEntity)
                .collect(Collectors.toList());
        rsList.stream().forEach(r -> {
            r.setBillId(billEntity.getId());
            r.setPutawayNum(0);
        });
        storeReceiveBillDetailService.saveBatch(rsList);
    }

    private void beforeOperation(Integer id) {
        StoreReceiveBillEntity checkEntity = storeReceiveBillService.getById(id);
        if(checkEntity.getStatus() != 0){
            throw new StoreException("收货单状态为待审核时才能进行状态操作!");
        }
    }

    public List<StoreReceiveSkuSelectBO> getReceiveList(Integer originOrderType, String originOrder) {
         switch (originOrderType){
             case 1:
                 return storePurchaseBillManager.getReceiveList(originOrder);
             default:
                 return Collections.emptyList();
         }
    }
}
